package com.sky.sky_server.service.impl;

import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.stream.Collectors;

import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.sky.sky_pojo.dto.BusinessDataVO;
import com.sky.sky_pojo.dto.OrderReportVO;
import com.sky.sky_pojo.dto.TOP10VO;
import com.sky.sky_pojo.dto.TurnoverReportVO;
import com.sky.sky_pojo.dto.UserReportVO;
import com.sky.sky_server.mapper.OrderDetailMapper;
import com.sky.sky_server.mapper.OrderMapper;
import com.sky.sky_server.mapper.UserMapper;
import com.sky.sky_server.service.ReportService;

import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class ReportServiceImpl implements ReportService{

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private OrderDetailMapper orderDetailMapper;

    @Autowired
    private WorkSpaceServiceImpl workSpaceServiceImpl;

    /**
     * 营业额统计
     */
    @Override
    public TurnoverReportVO turnoverStatistics(LocalDate begin, LocalDate end) {
        // 查询营业额数据

        // end格式化为当天23.59.59

        List<Double> turnoverList = orderMapper.turnoverStatistics(begin, end.atTime(23,59,59));

        // 生成日期列表
        List<LocalDate> dateList = new ArrayList<>();
        LocalDate cursor = begin;
        while(!cursor.isAfter(end)){
            dateList.add(cursor);
            cursor = cursor.plusDays(1);
        }

        // 判断两者是否等长
        log.info("dateList.size() = {}, turnoverList.size() = {}", dateList.size(), turnoverList.size());

        // 转换为字符串表示
        String dateListStr = dateList.stream().map(date -> date.toString()).collect(Collectors.joining(","));
        String turnoverListStr = turnoverList.stream().map(turnover -> turnover.toString()).collect(Collectors.joining(","));

        TurnoverReportVO turnoverReportVO = new TurnoverReportVO();
        turnoverReportVO.setDateList(dateListStr);
        turnoverReportVO.setTurnoverList(turnoverListStr);
        return turnoverReportVO;

    }

    @Override
    public UserReportVO userStatistics(LocalDate begin, LocalDate end) {
        // 日期列表
        LocalDate cursor = begin;
        List<LocalDate> dateList = new ArrayList<>();
        while(!cursor.isAfter(end)){
            dateList.add(cursor);
            cursor = cursor.plusDays(1);
        }

        // 新增用户数列表
        List<Integer> newUserList = userMapper.userStatistics(begin, end.atTime(23,59,59));

        // 总用户数列表
        List<Integer> totalUserList = new ArrayList<>();
        int totalUser = 0;
        for(Integer newUser : newUserList){
            totalUser += newUser;
            totalUserList.add(totalUser);
        }

        log.info("用户统计，三个列表的长度： dateList={}, newUserList={}, totalUserList={}", dateList.size(), newUserList.size(), totalUserList.size());
        // 三个列表拼接成字符串
        String dateListStr = dateList.stream().map(date -> date.toString()).collect(Collectors.joining(","));
        String newUserListStr = newUserList.stream().map(newUser -> newUser.toString()).collect(Collectors.joining(","));
        String totalUserListStr = totalUserList.stream().map(total -> total.toString()).collect(Collectors.joining(","));

        return new UserReportVO(dateListStr, newUserListStr, totalUserListStr);
    }

    /**
     * 订单统计
     */
    @Override
    public OrderReportVO orderStatistics(LocalDate begin, LocalDate end) {
        // 日期列表
        LocalDate cursor = begin;
        List<LocalDate> dateList = new ArrayList<>();
        while(!cursor.isAfter(end)){
            dateList.add(cursor);
            cursor = cursor.plusDays(1);
        }
        // 新增订单数列表,每日总数
        List<Integer> newOrderList = orderMapper.orderStatisticsDailyTotal(begin, end.atTime(23,59,59));
        // 订单总数
        Integer totalOrderCount = newOrderList.stream().mapToInt(Integer::intValue).sum();

        // 每日有效订单数
        List<Integer> validOrderList = orderMapper.orderStatisticsDailyValid(begin, end.atTime(23,59,59));
        // 有效订单总数
        Integer validOrderCount = validOrderList.stream().mapToInt(Integer::intValue).sum();

        // 订单完成率
        Double orderCompletionRate = (double) validOrderCount / totalOrderCount;

        log.info("订单统计三个列表的长度，dateList={},newOrderList={},validOrderList={}", dateList.size(), newOrderList.size(), validOrderList.size());

        // 三个列表转为字符串
        String dateListStr = dateList.stream().map(LocalDate::toString).collect(Collectors.joining(","));
        String newOrderListStr = newOrderList.stream().map(String::valueOf).collect(Collectors.joining(","));
        String validOrderListStr = validOrderList.stream().map(String::valueOf).collect(Collectors.joining(","));

        // 封装返回值
        OrderReportVO orderReportVO = new OrderReportVO();
        orderReportVO.setDateList(dateListStr);
        orderReportVO.setOrderCountList(newOrderListStr);
        orderReportVO.setValidOrderCountList(validOrderListStr);
        orderReportVO.setTotalOrderCount(totalOrderCount);
        orderReportVO.setValidOrderCount(validOrderCount);
        orderReportVO.setOrderCompletionRate(orderCompletionRate);

        return orderReportVO;

    }

    /**
     * 菜品销售排名
     */
    @Override
    public TOP10VO top10(LocalDate begin, LocalDate end) {
        List<Map<String, Object>> dishNamesMapList = orderDetailMapper.selectTop10DishNames(begin, end.plusDays(1));
        Map<String, Integer> dishNamesMap = null;
        //if(dishNamesMapList.size() > 0 && dishNamesMapList != null)
        dishNamesMap = dishNamesMapList.stream().collect(
            Collectors.toMap(
                map -> map.get("name").toString(),
                map -> ((Number) map.get("total")).intValue()
                )
        );
        List<Map<String, Object>> setmealNamesMapList = orderDetailMapper.selectTop10SetmealNames(begin, end.plusDays(1));

        Map<String, Integer> setmealNamesMap = null;
        //if(setmealNamesMapList.size() > 0 && setmealNamesMapList != null)
        setmealNamesMap = setmealNamesMapList.stream().collect(
            Collectors.toMap(
                map -> map.get("name").toString(),
                map -> ((Number) map.get("total")).intValue()
            )
        );

        log.info("菜品销售 查询结果 dishNamesMap: {} ", dishNamesMap);
        log.info("菜品销售 查询结果 setmealNamesMap: {} ", setmealNamesMap);
        // 优先级队列, 按照销售量排序
        PriorityQueue<Map.Entry<String, Integer>> queue = new PriorityQueue<>((o1, o2) ->{
            return -(o1.getValue() - o2.getValue());
        });
        if(dishNamesMap != null)
            queue.addAll(dishNamesMap.entrySet());
        if(setmealNamesMap != null)
            queue.addAll(setmealNamesMap.entrySet());

        List<String> names = new ArrayList<>();
        List<Integer> counts = new ArrayList<>();
        // 取出前10名 
        int index = 0;
        while(!queue.isEmpty() && index++ < 10){
            Map.Entry<String, Integer> entry = queue.poll();
            names.add(entry.getKey());
            counts.add(entry.getValue());
        }
        log.info("菜品销售 sorted result names: {} ", names);
        log.info("菜品销售 sorted result counts: {} ", counts);

        String namesStr = names.stream().collect(Collectors.joining(","));
        String countsStr = counts.stream().map(String::valueOf).collect(Collectors.joining(","));

        TOP10VO result = new TOP10VO();
        result.setNameList(namesStr);
        result.setNumberList(countsStr);

        return result;
    }

    /**
     * 导出运营数据报表
     */
    @Override
    public void exportBusinessData(HttpServletResponse response) {
        // 查询营业30天的营业数据
        LocalDate begin = LocalDate.now().minusDays(-1);
        
        // 查询概览数据
        BusinessDataVO businessDataVO = workSpaceServiceImpl.businessData(begin, begin.plusDays(-30));

        // 从资源加载中获取模板文件
        InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("templates/运营数据报表模板.xlsx");
        XSSFWorkbook excel = null;
        ServletOutputStream out = null;
        try {
            // 通过POI写入到excel文件
            excel = new XSSFWorkbook(inputStream);

            // 填充数据——时间
            XSSFSheet sheet = excel.getSheet("Sheet1");
            String timeStr = begin.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + " 至 " + begin.plusDays(-30).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            sheet.getRow(1).getCell(1).setCellValue("时间：" + timeStr);

            // 获得第四行
            XSSFRow row = sheet.getRow(3);
            row.getCell(2).setCellValue(businessDataVO.getTurnover()); // 营业额
            row.getCell(4).setCellValue(businessDataVO.getOrderCompletionRate()); // 订单完成率
            row.getCell(6).setCellValue(businessDataVO.getNewUsers()); // 新增用户数

            // 获得第五行
            row = sheet.getRow(4);
            row.getCell(2).setCellValue(businessDataVO.getValidOrderCount()); // 有效订单数
            row.getCell(4).setCellValue(businessDataVO.getUnitPrice()); // 平均客单价

            // 填充明细数据
            LocalDate beginDate = LocalDate.now();
            for(int i = -30; i < 0; i++){

                LocalDate date = beginDate.plusDays(i);
                
                // 查询当天的营业数据
                BusinessDataVO businessData = workSpaceServiceImpl.businessData(date, date);

                // 填充数据
                row = sheet.getRow(7 + i + 30);
                row.getCell(1).setCellValue(date.toString());
                row.getCell(2).setCellValue(businessData.getTurnover()); // 营业额
                row.getCell(3).setCellValue(businessData.getValidOrderCount()); // 有效订单数
                row.getCell(4).setCellValue(businessData.getOrderCompletionRate()); // 订单完成率
                row.getCell(5).setCellValue(businessData.getUnitPrice()); // 平均客单价
                row.getCell(6).setCellValue(businessData.getNewUsers()); // 新增用户数
            }



            // 获取输出流对象，并将excel文件写入到输出流中..将excel文件下载到客户端浏览器
            out = response.getOutputStream();
            excel.write(out);


        } catch (IOException e) {
            e.printStackTrace();
        } finally { // 关闭资源
            if(excel != null) {
                try {
                    excel.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        
    }

    
}
